package simulador;

// Classe que representa a chegada de um cliente. Deriva de Evento.

import smallsimulator.chegadaInfo;


public class Chegada extends Evento {
    private chegadaInfo info;
    
    private double media_serv, desvio_serv; // Variáveis para cálculos estatísticos
	
        private int esteId=0;
        private int tipoR = 0;
        
        private Aleatorio randGen;
        
    //Construtor
    Chegada (double i, Simulador s, chegadaInfo aInfo){
		super (i, s);
                info = aInfo;
                
                media_serv = info.getTempoMedio();
                desvio_serv = info.getDesvio();
                
                if(info.getTipoRandom().equals("log"))
                    tipoR = -1;
                else if(info.getTipoRandom().equals("nor"))
                    tipoR = 1;
                else
                    tipoR = 0;
                
                
                randGen = new Aleatorio(esteId);
	}

	// Método que executa as acções correspondentes à chegada de um cliente
    void executa (Servico serv){
	    // Coloca cliente no serviço - na fila ou a ser atendido, conforme o caso
		//serv.insereServico (new Cliente());
                s.transitaCliente(new Cliente(), 1);
        // Agenda nova chegada para daqui a Aleatorio.exponencial(s.media_cheg) instantes
		s.insereEvento (new Chegada(sortNextTempo(s.getInstante()), s,info));
                
	}
    
    public double sortNextTempo(double instante){
        if(tipoR<0){
            return instante+randGen.exponencial(this.media_serv);
        }else if(tipoR>0){
            //double calc = (1/Math.sqrt((2*Math.PI*desvio_serv)))*Math.exp(-1*(Math.pow(RandomGenerator.rand64(esteId)-media_serv, 2)/(2*Math.pow(desvio_serv, 2))));
            /*double calc = (1/Math.sqrt((2*Math.PI*1)))*Math.exp(-1*(Math.pow(RandomGenerator.rand64(esteId)*3, 2)/(2*Math.pow(1, 2))));
            System.out.println(""+calc);
            calc = media_serv+(calc*desvio_serv);
            return instante+calc;*/
            return instante+Math.abs(randGen.gaussian(media_serv, desvio_serv));
        }else {
            //double calc = media_serv+((desvio_serv*RandomGenerator.rand64(esteId))-(desvio_serv/2));
            return instante+randGen.uniform(media_serv, desvio_serv);
        }
    }

    // Método que descreve o evento.
    // Para ser usado na listagem da lista de eventos.
    public String toString(){
         return "Chegada em " + instante;
    }
}